package com.mauth.web.service.impl;

import com.mauth.common.entity.auth.AuthorizedCode;
import com.mauth.web.repository.AuthCodeRepository;
import com.mauth.web.service.AuthorizedCodeService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Optional;

@Service
public class AuthCodeServiceImpl implements AuthorizedCodeService {
    @Value("${system.expires}")
    private Integer expires;
    @Value("${system.code-length}")
    private Integer codeLength;
    @Resource
    private AuthCodeRepository authCodeRepository;


    @Override
    public AuthorizedCode generateCode(String userSeq, Integer clientId, Integer expires) {
        String randomAlphanumeric = RandomStringUtils.randomAlphanumeric(codeLength);
        Optional<AuthorizedCode> byCode = authCodeRepository.findByCode(randomAlphanumeric);
        AuthorizedCode code = new AuthorizedCode();
        while (byCode.isPresent()) {
            randomAlphanumeric = RandomStringUtils.randomAlphanumeric(codeLength);
            byCode = authCodeRepository.findByCode(randomAlphanumeric);
        }
        code.setCode(randomAlphanumeric);
        code.setClientId(clientId);
        code.setExpires(expires);
        code.setUserSeq(userSeq);
        return authCodeRepository.save(code);
    }

    @Override
    public boolean validCode(String code) {
        Optional<AuthorizedCode> byCode = authCodeRepository.findByCode(code);
        if (byCode.isPresent()) {
            Duration between = Duration.between(byCode.get().getCreateAt(), LocalDateTime.now());
            return between.abs().getSeconds() - expires <= 0;
        }
        return false;
    }

    @Override
    public void deleteAuthorizedCode(Integer id) {
        authCodeRepository.deleteById(id);
    }

    @Override
    public AuthorizedCode getAuthorizedCode(String code) {
        return authCodeRepository.findByCode(code).orElse(null);
    }
}
